{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "# How do you speak Matplotlib?"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "skip"
    }
   },
   "source": [
    "A *matplotlib* visualization is a `figure` onto which is attached one or more `axes`. Each `axes` has a horizontal (x) `axis` and vertical (y) `axis`, and the data is encoded using color and glyphs such as `markers` (for example circles) or `lines` or polygons (called `patches`). The figure below annotates these parts of a visualization and was created by Nicolas P. Rougier using `matplotlib`. The source code can be found in the [matplotlib documentation](https://matplotlib.org/gallery/showcase/anatomy.html#sphx-glr-gallery-showcase-anatomy-py)."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "![Diagram of the components of the matplotlib generated visualization.](../images/mpl_anatomy.png)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "# Import matplotlib & tell Jupyter to draw things"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "outputs": [],
   "source": [
    "%config InlineBackend.figure_format = 'retina'  # change this to png if your plots are too small\n",
    "%matplotlib inline\n",
    "import matplotlib.pyplot as plt\n",
    "import numpy as np"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "### What is this backend thing?"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "skip"
    }
   },
   "source": [
    "Backends are the rendering engines matplotlib use to transform the Python code into pixels on the screen. Matplotlib supports many different static and interactive [backends](https://matplotlib.org/3.1.0/api/index_backend_api.html). \n",
    "\n",
    "The following line of code prints the current backend:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "outputs": [],
   "source": [
    "import matplotlib\n",
    "matplotlib.get_backend()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "skip"
    }
   },
   "source": [
    "We told matplotlib to use the ipython inline backend when we typed `%matplotlib inline`\n",
    "\n",
    "the `inline` backend results in static, non-interactive images.  Later in this tutorial we will cover how to use interactive backends in the notebook."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "# Let's make that figure"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "skip"
    }
   },
   "source": [
    "A Matplotlib [figure](https://matplotlib.org/api/_as_gen/matplotlib.figure.Figure.html#matplotlib.figure.Figure) is like an empty sheet of paper (or a blank canvas) on which we will draw all our plots, images, and diagrams. Here, the ipython backend decided to not render anything because we have not yet added any plots to our figure."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "outputs": [],
   "source": [
    "plt.figure()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "# Figure+ Axes (plotting surface)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "outputs": [],
   "source": [
    "plt.subplots()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "skip"
    }
   },
   "source": [
    "The x and y ticks and the box let us know that the axes was created. Let's assign the output of `plt.subplots`-which is a helper function that creates the figure and axes-to variables so that we can manipulate the figure and axes directly. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "outputs": [],
   "source": [
    "fig, ax = plt.subplots()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "notes"
    }
   },
   "source": [
    "## Adjusting figure size\n",
    "We can make the figure bigger or smaller using the `figsize=(width, height)` keyword construction. The default is 8x6"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "slideshow": {
     "slide_type": "notes"
    }
   },
   "outputs": [],
   "source": [
    "fig, ax = plt.subplots(figsize=(4,2))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "# Add data to the figure using a plotting method"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "skip"
    }
   },
   "source": [
    "First, lets use `Pandas` to open our titanic dataset so that we have something to plot!"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "outputs": [],
   "source": [
    "import pandas as pd\n",
    "df = pd.read_csv(\"http://bit.ly/tcsv19\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "skip"
    }
   },
   "source": [
    "Matplotlib supports many, many, many different plot types. Peruse the [gallery](https://matplotlib.org/gallery.html) to find some you like! \n",
    "\n",
    "A hopefully full list of supported plot methods is at https://matplotlib.org/3.1.0/api/axes_api.html#plotting \n",
    "\n",
    "Here we will use the `ax.plot` method from our installation test. This function is usually used to create line plots, but it can be used to create scatter plots when the marker is set to `'o'`. We use `.plot` here instead of `.scatter` so that we do not have to generate x-values to plot against."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "outputs": [],
   "source": [
    "fig, ax = plt.subplots()\n",
    "_ = ax.plot(np.sort(df['age']), marker='o', markersize=1)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "skip"
    }
   },
   "source": [
    "__troubleshooting__:\n",
    "If your figure looks \"fuzzy\" it is likely you have a hi-dpi (aka 'retnia' display), try running\n",
    "\n",
    "```ipython\n",
    "%config InlineBackend.figure_format = 'retina'  # tell IPython to use hi-dpi pngs\n",
    "```   \n",
    "And then re-rendering your figure by typing `<shift> + <enter>` in the above notebook cell."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "# What are we plotting? Let's label"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "skip"
    }
   },
   "source": [
    "You can label almost everything in matplotlib. The most commonly used labeling methods are to set the:\n",
    "* title: `set_title`\n",
    "* x axis label: `set_xlabel`\n",
    "* y axis label: `set_ylabel`"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "outputs": [],
   "source": [
    "fig, ax = plt.subplots()\n",
    "_ = ax.set_title (\"Titanic Data Set\")\n",
    "_ = ax.plot(np.sort(df['age']), marker='o', markersize=1)\n",
    "_ = ax.set_ylabel(\"Ages\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "# Let's change up the y axis"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "Instead of breaking the ages up by 10, lets use the US census demographic groupings:\n",
    " * Children: 0–14 years\n",
    " * Youth: 15–24 years \n",
    " * Adult: 25–54 years \n",
    " * Older Adult: 55–64 years\n",
    " * Senior: 65 years and over"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "skip"
    }
   },
   "source": [
    "Ticks can primarily be customized in two ways:\n",
    "* [Locators](https://matplotlib.org/3.1.1/gallery/ticks_and_spines/tick-locators.html): where the tick is\n",
    "* [Formatters](https://matplotlib.org/3.1.1/gallery/ticks_and_spines/tick-formatters.html): what the tick looks like"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "skip"
    }
   },
   "source": [
    "First we use the `.set_yticks()` method to place our ticks according to the demographic group."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "outputs": [],
   "source": [
    "fig, ax = plt.subplots()\n",
    "_ = ax.set_title (\"Titanic Data Set\")\n",
    "_ = ax.plot(np.sort(df['age']), marker='o', markersize=1)\n",
    "_ = ax.set_ylabel(\"Ages\")\n",
    "_ = ax.set_yticks([15,25, 55, 64])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    " Now we use `.set_yticklabels()` to replace the labels that were automatically generated based on the tick locations with manually defined labels. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "outputs": [],
   "source": [
    "fig, ax = plt.subplots()\n",
    "_ = ax.set_title (\"Titanic Data Set\")\n",
    "_ = ax.plot(np.sort(df['age']), marker='o', markersize=1)\n",
    "_ = ax.set_ylabel(\"Ages\")\n",
    "_ = ax.set_yticks([15,25, 55, 64])\n",
    "_ = ax.set_yticklabels(['children', 'youth', 'adults', 'seniors'])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "# Putting it all together: Let's look at fares!\n",
    "\n",
    "* First Class Suite- £870 or $4,350\n",
    "\n",
    "* First Class Berth- £30 or $150\n",
    "\n",
    "* Second Class- £12 or $60\n",
    "\n",
    "* Third Class- £3 to £8 or $40\n",
    "\n",
    "source: (Wilkinson & Hamilton, 2011) from [Titanic: The Whole Iceberg](https://autumnmccordckp.weebly.com/tickets-and-accomodations.html)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "## Tasks\n",
    "1. Create a figure and an axis\n",
    "2. Plot the \"fare\" column\n",
    "3. Label the y-axis \"fare\"\n",
    "4. Set the y tick locations using the fare class boundaries: [3, 12, 30, 870]\n",
    "5. Set the y tick labels using the fare class boundaries: [3rd, 2nd, 1st B, 1st S]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "outputs": [],
   "source": [
    "#We'll work through the solution together here\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "# Let's put more than one image on the page"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "skip"
    }
   },
   "source": [
    "Matplotlib offers a lot of flexibility in creating images that have multiple figures, and you can read all about them in the [customizing figures tutorial](https://matplotlib.org/3.1.1/tutorials/intermediate/gridspec.html#sphx-glr-tutorials-intermediate-gridspec-py). We will briefly touch on using subplots, constrained_layout, and a drop of grid_spec. "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "## Multiple Axes"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "skip"
    }
   },
   "source": [
    "Let's put our two axes together on one figure, using `subplots` with the ncols kwarg to create a figure with two axes side by side. \n",
    "\n",
    "We can use the `Figure` method `suptitle` to put a figure-level title on the plot."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "outputs": [],
   "source": [
    "fig, (ax1, ax2) = plt.subplots(ncols=2)\n",
    "fig.suptitle('Next To (1x2)')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "skip"
    }
   },
   "source": [
    "If you want the axes to be one under the other, you can use `plt.subplots(nrows=2)`. You can also create a grid using `plt.subplots(ncols=2, nrows=2)`. In the grid case, plt.subplots returns a (nrows, ncols) shaped array of axes objects. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "slideshow": {
     "slide_type": "notes"
    }
   },
   "outputs": [],
   "source": [
    "fig, (ax1, ax2) = plt.subplots(nrows=2)\n",
    "_ = fig.suptitle('Stacked (2x1)')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "slideshow": {
     "slide_type": "notes"
    }
   },
   "outputs": [],
   "source": [
    "fig, axes = plt.subplots(nrows=2, ncols=2)\n",
    "_ = fig.suptitle('Quad (2x2)')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "outputs": [],
   "source": [
    "fig, (ax1, ax2) = plt.subplots(ncols=2)\n",
    "_ = fig.suptitle(\"Titanic Data Set\")\n",
    "_ = ax1.plot(np.sort(df['age']), marker='o', markersize=1)\n",
    "_ = ax1.set_ylabel(\"Ages\")\n",
    "_ = ax1.set_yticks([15,25, 55, 64])\n",
    "_ = ax2.set_ylabel('Fare')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "## Yuck, crowded! Constrained Layout"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "[Constrained layout](https://matplotlib.org/3.1.1/tutorials/intermediate/constrainedlayout_guide.html) is matplotlib automagic that tries to place all the elements of the image on the page such that they don't overlap but the image still has breathing room and the users instructions are respected. It is especially useful when plotting multiple images. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "fig, (ax1, ax2) = plt.subplots(ncols=2, constrained_layout=True)\n",
    "_ = fig.suptitle(\"Titanic Data Set\")\n",
    "_ = ax1.plot(np.sort(df['age']), marker='o', markersize=1)\n",
    "_ = ax1.set_ylabel(\"Ages\")\n",
    "_ = ax1.set_yticks([15,25, 55, 64])\n",
    "_ = ax2.set_ylabel('Fare')\n",
    "# Exercise plote the fare data in the right axes"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "# Making images different sizes"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "There's a full [Gridspec API](https://matplotlib.org/3.1.1/api/gridspec_api.html#module-matplotlib.gridspec) that you can make use of, but here we will take a shortcut and use the `gridspec_kw` argument to plt.subplots(). `gridspec_kw` is a dictionary of all the keyword arguments that can be passed into Gridspec class objects.\n",
    "\n",
    "Here, we want one image to be much thinner than the second, so we will pass the `width_ratios` argument to gridspec_kw. Here, we say we want the second plot to be 3 times wider than the first."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "outputs": [],
   "source": [
    "fig, (ax1, ax2) = plt.subplots(ncols=2, gridspec_kw={'width_ratios':[1,3]}, constrained_layout=True)\n",
    "_ = fig.suptitle (\"Titanic Data Set\")\n",
    "_ = ax1.plot(np.sort(df['age']), marker='o', markersize=1)\n",
    "_ = ax1.set_ylabel(\"Ages\")\n",
    "_ = ax1.set_yticks([15,25, 55, 64])\n",
    "_ = ax2.set_ylabel('Fare')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "# Practice:\n",
    "1. Flip-make the ages graph wider than the fares graph\n",
    "2. Rotate: put the ages graph on top of the fares graph\n",
    "3. Top-heavy: in the vertical orientation from 2, make the ages graph larger \n",
    "    + hint: there's a `height_ratios` gridspec_kw"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "celltoolbar": "Slideshow",
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.3"
  },
  "latex_envs": {
   "LaTeX_envs_menu_present": true,
   "autoclose": false,
   "autocomplete": true,
   "bibliofile": "biblio.bib",
   "cite_by": "apalike",
   "current_citInitial": 1,
   "eqLabelWithNumbers": true,
   "eqNumInitial": 1,
   "hotkeys": {
    "equation": "Ctrl-E",
    "itemize": "Ctrl-I"
   },
   "labels_anchors": false,
   "latex_user_defs": false,
   "report_style_numbering": false,
   "user_envs_cfg": false
  },
  "varInspector": {
   "cols": {
    "lenName": 16,
    "lenType": 16,
    "lenVar": 40
   },
   "kernels_config": {
    "python": {
     "delete_cmd_postfix": "",
     "delete_cmd_prefix": "del ",
     "library": "var_list.py",
     "varRefreshCmd": "print(var_dic_list())"
    },
    "r": {
     "delete_cmd_postfix": ") ",
     "delete_cmd_prefix": "rm(",
     "library": "var_list.r",
     "varRefreshCmd": "cat(var_dic_list()) "
    }
   },
   "types_to_exclude": [
    "module",
    "function",
    "builtin_function_or_method",
    "instance",
    "_Feature"
   ],
   "window_display": false
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
